import { GLOBAL_CONFIG } from '@/const/storage'
import { DARK_THEME } from '@/const/theme'
import { isString, isObject, isNumber, isStringNumber } from '@/utils/type'
import { isHexColor } from '@/utils/regexp'
import { isPrefersReducedMotion, toCamelCase } from '@/utils/utils'
import { getStorage, setStorage } from './storage'

// hex颜色转rgb颜色
function hexToRgb(str) {
  str = str.replace('#', '')
  let hxs = str.match(/../g)
  for (let i = 0; i < 3; i++) hxs[i] = parseInt(hxs[i], 16)
  return hxs
}

// rgb颜色转hex颜色
function rgbToHex(a, b, c) {
  let hex = [a.toString(16), b.toString(16), c.toString(16)]
  for (let i = 0; i < 3; i++) {
    if (hex[i].length === 1) hex[i] = '0' + hex[i]
  }
  return '#' + hex.join('')
}

// 变淡
export function lighten(color, level) {
  let rgba = hexToRgb(color)
  for (let i = 0; i < 3; i++)
    rgba[i] = Math.floor((255 - rgba[i]) * level + rgba[i])
  return rgbToHex(rgba[0], rgba[1], rgba[2])
}

// 加深
export function darken(color, level) {
  let rgba = hexToRgb(color)
  for (let i = 0; i < 3; i++) rgba[i] = Math.floor(rgba[i] * (1 - level))
  return rgbToHex(rgba[0], rgba[1], rgba[2])
}

// 添加暗黑样式
export function addThemeClass(mode) {
  if (!isString(mode))
    throw new Error(`必须传入一个字符串类型的参数，而不是${typeof mode}`)

  setStorage(GLOBAL_CONFIG, { ...getStorage(GLOBAL_CONFIG), theme: mode })
  // EXPLAIN: 没必要再去调用useConfigStore
  document.documentElement.classList[mode === DARK_THEME ? 'add' : 'remove'](
    DARK_THEME,
  )
}

// 切换暗黑主题, 添加动画
export function changeThemeTransition(event, mode, callback) {
  if (!document.startViewTransition || isPrefersReducedMotion()) {
    addThemeClass(mode)
    console.warn('该浏览器不支持新特性或者开启了动画减弱')
    return
  }

  const transition = document.startViewTransition(() => addThemeClass(mode))
  const x = event.clientX
  const y = event.clientY
  const targetRadius = Math.hypot(
    Math.max(x, window.innerWidth - x),
    Math.max(y, window.innerHeight - y),
  )
  const clipPath = [
    `circle(0px at ${addUnit(x)} ${addUnit(y)})`,
    `circle(${addUnit(targetRadius)} at ${addUnit(x)} ${addUnit(y)})`,
  ]
  const isDark = mode === DARK_THEME

  transition.ready.then(() => {
    document.documentElement.animate(
      { clipPath: isDark ? clipPath : [...clipPath].reverse() },
      {
        duration: 500,
        easing: 'ease-in',
        pseudoElement: `::view-transition-${isDark ? 'new' : 'old'}(root)`,
      },
    )
  })

  transition.finished.then(() => callback && callback())
}

// 切换主题色
export function changePrimaryColor(color) {
  if (!isHexColor(color)) throw new Error('你必须传入一个16进制的color值')

  const namespace = '--el-color-primary'
  document.documentElement.style.setProperty(namespace, color)
  for (let i = 1; i <= 9; i++) {
    document.documentElement.style.setProperty(
      `${namespace}-light-${i}`,
      lighten(color, i / 10),
    )
  }
  for (let i = 1; i <= 9; i++) {
    document.documentElement.style.setProperty(
      `${namespace}-darken-${i}`,
      darken(color, i / 10),
    )
  }
}

// 切换灰色、弱色
export function changeWeakOrGreyMode(type, value) {
  const body = document.body
  if (!value) return body.removeAttribute('style')

  const stylesMap = {
    grey: 'filter: grayscale(1)',
    weak: 'filter: invert(80%)',
  }
  body.setAttribute('style', stylesMap[type])
}

// 获取单个css变量值
export function getCssPropertyValue(namespace) {
  return getComputedStyle(document.documentElement).getPropertyValue(namespace)
}

// 设置单个css变量值
export function setCssPropertyValue(namespace, value) {
  document.documentElement.style.setProperty(namespace, value)
}

// 转换内联样式: style="width: 50px; margin-right: 50px" ----> style: { width: '50px', marginRight: '50px' }
export function transformCustomStyle(style) {
  if (isObject(style)) return style
  return style
    .split(';')
    .filter(Boolean)
    .reduce((styleObject, style) => {
      let [key, value] = style.split(':').map((item) => item.trim())
      if (key.includes('-')) {
        key = toCamelCase(key)
      }
      styleObject[key] = value
      return styleObject
    }, {})
}

/**
 * @description 添加单位
 * @param {string | number} value
 * @param {string} unit
 * @returns {string | number}
 */
export function addUnit(value, unit = 'px') {
  if (!value) return ''
  if (isNumber(value) || isStringNumber(value)) {
    return `${value}${unit}`
  } else if (isString(value)) {
    return value
  }
}

/**
 * 根据传入的颜色值计算禁用的颜色
 * @param {string} hexColor - 十六进制颜色值，例如 "#3498db"
 * @param {number} [factor=0.5] - 调整颜色的因子，默认为0.7
 * @returns {string} - 计算后的禁用颜色值
 */
export function getDisabledColor(hexColor, factor = 0.5, alpha = 0.8) {
  // 确保颜色值以 "#" 开头
  if (hexColor.startsWith('#')) {
    hexColor = hexColor.slice(1)
  }

  // 将颜色值分解为 RGB
  let r = parseInt(hexColor.substring(0, 2), 16)
  let g = parseInt(hexColor.substring(2, 4), 16)
  let b = parseInt(hexColor.substring(4, 6), 16)

  // 计算禁用颜色
  r = Math.min(255, Math.floor(r + (255 - r) * factor))
  g = Math.min(255, Math.floor(g + (255 - g) * factor))
  b = Math.min(255, Math.floor(b + (255 - b) * factor))

  return `rgba(${r}, ${g}, ${b}, ${alpha})`
}

export function hexToRgba(hex, alpha = 1) {
  // 去掉可能的前缀#
  hex = hex.replace(/^#/, '')

  // 解析颜色值
  let r, g, b
  if (hex.length === 3) {
    r = parseInt(hex[0] + hex[0], 16)
    g = parseInt(hex[1] + hex[1], 16)
    b = parseInt(hex[2] + hex[2], 16)
  } else if (hex.length === 6) {
    r = parseInt(hex.slice(0, 2), 16)
    g = parseInt(hex.slice(2, 4), 16)
    b = parseInt(hex.slice(4, 6), 16)
  } else {
    throw new Error('Invalid hex color format')
  }

  // 返回rgba格式
  return `rgba(${r}, ${g}, ${b}, ${alpha})`
}

export function changeAsideStyle(isDarkAside) {
  document.documentElement.classList[isDarkAside ? 'add' : 'remove'](
    'dark-aside',
  )
}
